/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TeoriaDeColas;

import java.util.concurrent.Semaphore;
import javax.swing.JLabel;

/**
 * clase que inicializa a un cliente del sistema, se representa por medio de 
 * de un label graficamente
 * @author Karadak
 */
public class Cliente extends JLabel implements Runnable 
{
    private double tiempoServicio;  // por cuanto tiempo esta en el servicio
    private double tiempoSistema;   // tiempo que pasa en el sistema
    private boolean activo;         // bandera de actividad
    private Thread hilo;            // vida del cliente
    private Semaphore semaforo;     // semaforo de acciones    
    public Semaphore semaforo_aux;  // auxiliar
    
    private int yCoordenada = 25;   // coordenada en el tablero grafico
    
    public Cliente()
    {     
        // damos las propiedades graficas al Label
        setBounds(0,yCoordenada, 64, 64);
        setIcon(new javax.swing.ImageIcon(getClass().getResource("/Iconos/Simulador/Cliente.png")));
        
        tiempoSistema = 0;
        tiempoServicio = 0;
        activo = true;
        semaforo = new Semaphore(0, true);
        semaforo_aux = new Semaphore(0, true);
        hilo = new Thread(this);
        
        Variables_Globales.hilos.add(hilo);
        
         // nos permite animar la entrada del cliente
        Thread entrar = new Thread(new Runnable() 
        {

            public void run() {
                try
                {
                    EntraCliente();
                } 
                catch (Exception er) 
                {
                    System.out.println("Error RUN(): Cliente constructor "+er);
                }
            }
        });        

       entrar.start();
       hilo.start();
       
        // nos permite animar la salida del cliente
       Thread terminar = new Thread(new Runnable() 
       {
           public void run() 
           {
               try 
               {                   
                    GUI.XtendSimulador.LenghtCola();
                    
                    semaforo.acquire();                
                    GUI.XtendSimulador.LenghtCola();
                    activo = false;
               }
               catch (Exception err) 
               {
                   System.out.println("Error RUN():terminar "+err);
               }
            }
        });
        Variables_Globales.hilos.add(terminar);
        terminar.start();
    }

    @Override
    public void run() 
    {
        try 
        {             
            while (activo) 
            {
               
                tiempoSistema++;                // contador de tiempo en el sistema
                
                Thread.sleep(Variables_Globales.velocidad_simulador);    
                
                while(Variables_Globales.pausar_simulador)
                {
                    Thread.sleep(100);
                }
            }
            System.out.println("    cliente en el sistema "+tiempoSistema);
            ClienteSatisfecho();
            
        } 
        catch (Exception err) 
        {
            System.err.println("error en RUN() cliente "+err);
        }
    }

    
    
    public double getTiempoSistema() {
        return tiempoSistema;
    }

    public double getTiempoServicio() {
        return tiempoServicio;
    }

    public void setTiempoServicio(double tiempoServicio) {
        this.tiempoServicio = tiempoServicio;
    }
    
    public void terminar() {
        semaforo.release();
    }
       
    /**
     * anima la entrada del cliente al sistema
     * @throws Exception 
     */
    private void EntraCliente() throws Exception
    {
        int cord_x = 0;
        setBounds(cord_x, yCoordenada, 64, 64);
        
        while (cord_x <= 111) 
        {
            cord_x += 11;
            setBounds(cord_x, yCoordenada, 64, 64);
            Thread.sleep(30);
            while(Variables_Globales.pausar_simulador)
            {
                Thread.sleep(100);
            }
        }      
        setBounds(777, 777, 64, 64);
        semaforo_aux.release();
    }
    
    /**
     * anima la salida de la cola 
     * @throws Exception 
     */
    public void salidaCola() throws Exception 
    {
        int cord_x = 0;
        
        setBounds(0, this.yCoordenada, 64, 64);
        
        while (cord_x <= 131) 
        {
            cord_x += 11;
            setBounds(cord_x, this.yCoordenada, 64, 64);
            Thread.sleep(60);
            while(Variables_Globales.pausar_simulador)
            {
                Thread.sleep(100);
            }
        }
        setBounds(777, 777, 64, 64);
        semaforo_aux.release();
    }    
    
    /**
     * el cliente sale del servicio hacia la salida del sistema
     * @throws Exception 
     */
    private void ClienteSatisfecho() throws Exception 
    {
        int cord_x = 0;
        
        setBounds(55, this.yCoordenada, 64, 64);
        while (cord_x <= 222) 
        {
            cord_x += 11;
            setBounds(cord_x, this.yCoordenada, 64, 64);
            Thread.sleep(30);
            while(Variables_Globales.pausar_simulador)
            {
                Thread.sleep(100);
            }
        }        
        GUI.XtendSimulador.cuantosSalen();
        setBounds(777, 777, 64, 64);
        semaforo_aux.release();
    }
}
